package org.itboys.store.manager;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.lang3.StringUtils;
import org.itboys.admin.cache.SysDictionaryLoader;
import org.itboys.admin.service.SysDictionaryService;
import org.itboys.commons.CommonConstants;
import org.itboys.commons.utils.json.JsonUtils;
import org.itboys.framework.resource.ResourceHolder;
import org.itboys.fuzion.constant.FuzionConstants;
import org.itboys.fuzion.dto.FuzionMemberDto;
import org.itboys.fuzion.dto.FuzionMemberRedisDto;
import org.itboys.fuzion.entity.IncomeExpenditureRecords;
import org.itboys.fuzion.kuaiqian.KQPayInfo;
import org.itboys.fuzion.kuaiqian.KQResult;
import org.itboys.fuzion.kuaiqian.KQService;
import org.itboys.fuzion.mysql.dao.FuziongMemberStatisticsMapper;
import org.itboys.fuzion.mysql.orm.FuziongMemberStatistics;
import org.itboys.fuzion.mysql.service.FuziongMemberStatisticsService;
import org.itboys.fuzion.service.FuzionMemberService;
import org.itboys.fuzion.service.IncomeExpenditureRecordsService;
import org.itboys.solr.client.SolrClient;
import org.itboys.store.dto.ProductDetail;
import org.itboys.mongodb.utils.page.Page;
import org.itboys.pay.alipay.AlipayWapResult;
import org.itboys.pay.weixin.WXPayService;
import org.itboys.pay.weixin.WeixinPaySignTool;
import org.itboys.pay.weixin.WeixinPayUtils;
import org.itboys.store.cache.ProductDetailLoader;
import org.itboys.store.constant.ProductConstant;
import org.itboys.store.dto.ConfirmOrderDto;
import org.itboys.store.dto.ConfirmProductDto;
import org.itboys.store.entity.*;
import org.itboys.store.search.ProductSearchDoc;
import org.itboys.store.search.ProductSearchService;
import org.itboys.store.service.*;
import org.itboys.store.tools.CloudBuilderInteface;
import org.itboys.store.tools.OrderItemList;
import org.itboys.store.tools.UserInfo;
import org.itboys.redis.RedisCacheClient;
import org.itboys.weixin.entity.WeixinConfig;
import org.itboys.weixin.service.WeixinConfigService;
import org.itboys.weixin.service.WeixinSendInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import weibo4j.org.json.JSONArray;
import weibo4j.org.json.JSONObject;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class StoreOrderMemberService {
	
	protected Logger logger = LoggerFactory.getLogger(getClass());

	@Resource(name = "storeProductDetailLoader")
	private ProductDetailLoader productDetailLoader;
	@Resource(name="sysDictionaryLoader")
	private SysDictionaryLoader sysDictionaryLoader;
	@Resource(name = "storeProductSolrClient")
	private SolrClient productSolrClient;

    @Autowired
    private WeixinConfigService weixinConfigService;
    @Autowired
    private StoreOrderService orderService;
	@Autowired
	private StoreOrderItemService orderItemService;
	@Autowired
	private RedisCacheClient redisCacheClient;
	@Autowired
	private SysDictionaryService sysDictionaryService;
	@Autowired
	private WeixinSendInfoService weixinSendInfoService;
	@Autowired
	private StoreReceiveAddressService receiveAddressService;
	@Autowired
	private StoreProductStorageService productStorageService;
	@Autowired
	private StoreCarItemService carItemService;
	@Autowired
	private FuzionMemberService memberService;
	@Autowired
	private StoreProductService productService;
	@Autowired
	private StoreOrderPayRecordService orderPayRecordService;
	@Autowired
	private StoreProductCountService storeProductCountService;
	@Autowired
	private ProductSearchService productSearchService;
	@Autowired
	private ResourceHolder resourceHolder;
	@Autowired
	private StoreProductStorageService storeProductStorageService;
	@Autowired
	private FuziongMemberStatisticsService fuziongMemberStatisticsService;
	@Autowired
	private FuziongMemberStatisticsMapper fuziongMemberStatisticsMapper;
	@Autowired
	private IncomeExpenditureRecordsService incomeExpenditureRecordsService;

	private static final String QK_NOTIFY_FAIL = "<result>2</result><redirecturl></redirecturl>";
	private static final String QK_NOTIFY_SUCCESS = "<result>1</result><redirecturl>{url}</redirecturl>";

	/**
	 * 生成立即购买确认订单页面的数据
	 * @param productId
	 * @param memberId
     * @return
     */
	public ConfirmOrderDto buyNow(Long productId, Long memberId, Integer num, Long addressId){
		ProductDetail detail = productDetailLoader.get(productId);
		//判断库存
		Integer store = sysDictionaryLoader.get(ProductConstant.CACHE_STORE_LIMIT);
		Integer postFee = sysDictionaryLoader.get(ProductConstant.CACHE_POST_FEE);
		Integer manPostFee = sysDictionaryLoader.get(ProductConstant.CACHE_MAN_POST);
		if(detail.getStore()-store <= num){//库存低于临界值  不允许购买
			return null;
		}
		ReceiveAddress receiveAddress = null;
		if(addressId != null){
			receiveAddress = receiveAddressService.getById(addressId);
		} else {
			receiveAddress = receiveAddressService.getMemberDefualtAddress(memberId);
		}
		ConfirmProductDto productDto = new ConfirmProductDto(detail, num, postFee, manPostFee);
		ProductStorage productStorage = storeProductStorageService.getByField("name", detail.getStorage());
		if(StringUtils.isNotBlank(productStorage.getViewName())){
			productDto.setDeliveryMethod(productStorage.getViewName());
		}
		ConfirmOrderDto orderDto = new ConfirmOrderDto();
		orderDto.setReceiveAddress(receiveAddress);
		orderDto.setProducts(Lists.newArrayList(productDto));
		orderDto.setNum(productDto.getNum());
		orderDto.setPrice(new BigDecimal(productDto.getPrice()).setScale(2));
		orderDto.setType(productDto.getType());
		return orderDto;
	}

	/**
	 * 立即购买创建订单
	 * @param productId
	 * @param memberId
	 * @param num
	 * @param couponId
	 * @param payMethod
	 * @param addressId
     * @param memo
     */
	@Transactional
	public Object buyNowCreateOrder(Long productId, Long memberId, int num, Long couponId, String spbillCreateIp,
								  Integer payMethod, Long addressId, String memo) throws Exception{
		Product product = productService.getById(productId);//产品信息  回滚用
		Long orderId = null;//订单id  回滚用
		Long orderItemId = null;//订单行id  回滚用
		Long recordId = null;
		try {
			ProductDetail detail = productDetailLoader.getDetail(product);
			//判断库存
			Integer store = sysDictionaryLoader.get(ProductConstant.CACHE_STORE_LIMIT);
			if(detail.getStore() - store < num){//库存低于临界值  不允许购买
				return -3;
			}
			OrderItemList orderItemList = new OrderItemList();
			UserInfo userInfo = new UserInfo();
			ReceiveAddress receiveAddress = receiveAddressService.getById(addressId);
			//填充orderItemList和userInfo
			fillParam(memberId, num, detail, orderItemList, userInfo, receiveAddress);

			Order order = new Order();
			//向海沧那边确认订单
			JSONObject object = new JSONObject();
			List<OrderItemList> orderItemLists = Lists.newArrayList(orderItemList);
			JSONArray array = new JSONArray();
			for (OrderItemList orderitemList :
					orderItemLists) {
				JSONObject jo = new JSONObject();
				jo.put("goodsId", orderitemList.getGoodsId());
				jo.put("skuId", orderitemList.getSkuId());
				jo.put("buyAmount", orderitemList.getBuyAmount());
				array.put(jo);
			}
			object.put("orderItemList", array);
			String itemStr = object.toString();
			object = new JSONObject();
			object.put("userInfo", new JSONObject(userInfo));
			//JSONObject objectUser = new JSONObject();
			//objectUser.put("userInfo",object);
			if(detail.getType().equals(Product.TYPE_HT)){
				Integer result = CloudBuilderInteface.orderInfoConfirmation(order.getOrderNo(), itemStr, object.toString());
				if(!result.equals(HttpStatus.SC_OK)){//确认订单异常
					return -1;
				}
			}
			order.setMemberId(memberId);
			order.setPayMethod(payMethod);
			order.setCreateTime(new Date());
			order.setUpdateTime(new Date());
			order.setName(receiveAddress.getName());
			order.setMobile(receiveAddress.getMobile());
			order.setAddress(receiveAddress.getAddress());
			order.setIdentityNo(receiveAddress.getIdentityNo());
			order.setNum(num);
			Integer postFee = sysDictionaryLoader.get(ProductConstant.CACHE_POST_FEE);
			Integer manPostFee = sysDictionaryLoader.get(ProductConstant.CACHE_MAN_POST);
			if(detail.getRealPrice()*num >= manPostFee){//满足包邮条件
				order.setExpressFee(0);
				order.setTotalFee(new BigDecimal(detail.getRealPrice() * 100).intValue() * num );
			} else {
				order.setExpressFee(detail.getPostage() * 100);
				order.setTotalFee(new BigDecimal((postFee + detail.getRealPrice() * num) * 100).intValue() );
			}
			order.setMemo(memo);
			//向海仓那边下单
			if(detail.getType().equals(Product.TYPE_HT)){
				Integer result = CloudBuilderInteface.bookorder(order.getOrderNo(), itemStr, object.toString());
				if(!result.equals(HttpStatus.SC_OK)){//下单异常
					return -1;
				}
			}
			orderService.save(order);
			orderId = order.getId();
			OrderItem item = new OrderItem();
			item.setOrderId(order.getId());
			item.setProductId(detail.getId());
			item.setProductName(detail.getTitle());
			item.setProductImg(detail.getImageUrl());
			item.setNum(num);
			item.setTotalFee(new BigDecimal(detail.getRealPrice() * 100).intValue() * num );//以分为单位
			item.setMemberId(memberId);
			item.setCreateTime(new Date());
			item.setUpdateTime(new Date());
			orderItemService.save(item);
			orderItemId = item.getId();
			//支付
			OrderPayRecord record = new OrderPayRecord();
			record.setOrderIds(Lists.newArrayList(order.getId()));
			orderPayRecordService.save(record);
			FuzionMemberRedisDto member = memberService.getFuzionMemberRedisDto(memberId);
			if(detail.getType().equals(Product.TYPE_SCORE)){//积分商城的产品直接扣除积分
				FuziongMemberStatistics fuziongMemberStatistics = fuziongMemberStatisticsService.getByMember(memberId);
				if(fuziongMemberStatistics.getNowTotalMoney() - order.getTotalFee() < 0){ //积分不足
					return -2;
				} else {
					fuziongMemberStatistics.setNowTotalMoney(fuziongMemberStatistics.getNowTotalMoney() - order.getTotalFee());
					fuziongMemberStatisticsService.update(fuziongMemberStatistics);
					order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_PAY);
					order.setPayTime(new Date());
					orderService.update(order);
					return 0;
				}
			}
			/*WeixinConfig weixinConfig = weixinConfigService.getById(Long.valueOf(member.getWeixinId()));
			WeixinPaySignTool weixinPaySignTool = WeixinPayUtils.paySign(weixinConfig.getAppId(), weixinConfig.getMchId(), member.getOpenId(),
					record.getOrderNo(), spbillCreateIp, ProductConstant.WeixinPay.TRADETYPE, "购买产品"+product.getTitle(),
					order.getTotalFee()+StringUtils.EMPTY, resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL, weixinConfig.getMcKkey());*/
			KQPayInfo info = new KQPayInfo(order.getOrderNo(), new BigDecimal(order.getTotalFee()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_DOWN),
					order.getMemberId(), "能量豆", order.getNum().toString(), resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL + "/" + order.getOrderNo(), "");
			String result = KQService.postAndResult(info);
			logger.info("******************KQService result***************" + result);
			// 减产品库存
			Product product1 = product;
			product1.setStore(product1.getStore() - num);
			productService.update(product1);
			//增加产品的销量
			storeProductCountService.update(productId, "soldCount", detail.getSoldCount() + num);
			productDetailLoader.clearCache(productId);
			return result;
		} catch (Exception e) {
			if(orderId != null){
				orderService.delete(orderId);
			}
			if(orderItemId != null){
				orderItemService.delete(orderItemId);
			}
			if(recordId != null){
				orderPayRecordService.delete(recordId);
			}
			if(product != null){
				productService.update(product);
			}
			throw new RuntimeException(e);
		} finally {
			productDetailLoader.clearCache(productId);
			ExecutorService fixedThreadPool = Executors.newSingleThreadExecutor();//开启线程  往搜索引擎里加信息
			fixedThreadPool.execute(new Runnable(){
				@Override
				public void run() {
					try {
						productSolrClient.deleteDocument(productId.toString());
						ProductDetail detail = productDetailLoader.get(productId);
						ProductSearchDoc doc = new ProductSearchDoc();
						doc.setProductId(productId);
						doc.setBrandId(detail.getBrandId());
						doc.setCategoryFullIdPath(detail.getCatId().toString());
						doc.setProductName(detail.getTitle() + ":::" + detail.getBrandName() + ":::" + detail.getCatName());
						doc.setPrice(detail.getRealPrice());
						doc.setSoldCount(detail.getSoldCount());
						doc.setReadCount(detail.getReadCount());
						doc.setType(detail.getType());
						productSearchService.buildProductSearchIndex(doc);
					} catch (Exception e) {
						logger.error("buyNowCreateOrder error", e);
					}
				}
			});
		}
	}

	/**
	 * 填充数据
	 * @param memberId
	 * @param num
	 * @param detail
	 * @param orderItemList
	 * @param userInfo
     * @param receiveAddress
     */
	private void fillParam(Long memberId, int num, ProductDetail detail, OrderItemList orderItemList, UserInfo userInfo, ReceiveAddress receiveAddress) {
		orderItemList.setSkuId(detail.getSkuId());
		orderItemList.setGoodsId(detail.getGoodsId());
		orderItemList.setBuyAmount(num);
		userInfo.setAccountId(memberId.toString());
		userInfo.setName(receiveAddress.getName());
		userInfo.setMobile(receiveAddress.getMobile());
		userInfo.setEmail(receiveAddress.getEmail());
		userInfo.setProvinceName(receiveAddress.getProvinceName());
		userInfo.setCityName(receiveAddress.getCityName());
		userInfo.setDistrictName(receiveAddress.getDistrictName());
		userInfo.setAddress(receiveAddress.getAddress());
		userInfo.setIdentityName(receiveAddress.getName());
		userInfo.setIdentityId(receiveAddress.getIdentityNo());
//		userInfo.setIdentityFrontImage(receiveAddress.getIdentityFrontImage());
//		userInfo.setIdentityOppImage(receiveAddress.getIdentityOppImage());
	}

	/**
	 * 购物车转订单时的确认订单页面
	 * @param memberId
	 * @param carIds
     * @return
     */
	public ConfirmOrderDto carConfirm(Long memberId, List<Long> carIds, Long addressId){
		ConfirmOrderDto dto = new ConfirmOrderDto();
		List<CarItem> carItems = carItemService.getByIds(carIds);
		ReceiveAddress receiveAddress = null;
		if(addressId != null){
			receiveAddress = receiveAddressService.getById(addressId);
		} else {
			receiveAddress = receiveAddressService.getMemberDefualtAddress(memberId);
		}
		dto.setReceiveAddress(receiveAddress);
		List<ConfirmProductDto> productDtos = Lists.newArrayListWithExpectedSize(carItems.size());
		int num = 0;
		double price = 0d;
		Integer postFee = sysDictionaryLoader.get(ProductConstant.CACHE_POST_FEE);
		Integer manPostFee = sysDictionaryLoader.get(ProductConstant.CACHE_MAN_POST);
		for (CarItem carItem : carItems) {
			ProductDetail detail = productDetailLoader.get(carItem.getProductId());
			ConfirmProductDto productDto = new ConfirmProductDto(detail, carItem.getNum(), postFee, manPostFee);
			ProductStorage productStorage = storeProductStorageService.getByField("name", detail.getStorage());
			if(StringUtils.isNotBlank(productStorage.getViewName())){
				productDto.setDeliveryMethod(productStorage.getViewName());
			}
			productDto.setCarId(carItem.getId());
			productDtos.add(productDto);
			num += carItem.getNum();
			price += carItem.getPrice() * carItem.getNum();
		}
		dto.setProducts(productDtos);
		dto.setNum(num);
		dto.setPrice(new BigDecimal(price).setScale(2));
		dto.setType(productDtos.get(0).getType());
		return dto;
	}

	/**
	 * 购物车转订单
	 * @param memberId
	 * @param carIds
	 * @param addressId
	 * @param payMethod
	 * @param memo
	 * @return
     * @throws Exception
     */
	@Transactional
	public Object carToOrder(Long memberId, List<Long> carIds, Long addressId, Integer payMethod, String memo, String spbillCreateIp) throws Exception{
		List<Long> orderIds = Lists.newArrayList();//用于 装载手动回滚时的orderId
		List<Long> orderItemIds = Lists.newArrayList();//用于装载手动回滚时的orderItemId
		List<Product> ops = Lists.newArrayList();//用于装载产品信息  便于库存的回滚
		Long recordId = null;
		List<ProductCount> counts = Lists.newArrayList();
		List<Long> pids = null;
		List<Order> orders = Lists.newArrayList();
		try {
			List<CarItem> cars = carItemService.getByIds(carIds);
			pids = Lists.transform(cars, car -> {
				return car.getProductId();
			});
			List<ProductCount> counts1 = storeProductCountService.getByIds(pids);
			counts = counts1;
			List<Product> products = productService.getByIds(pids);
			ops = products;
			//第一步  判断产品库存
			Integer store = sysDictionaryLoader.get(ProductConstant.CACHE_STORE_LIMIT);
			for (CarItem carItem : cars) {
				Product product = products.stream().filter(product1 -> carItem.getProductId().equals(Long.valueOf(product1.getId())))
						.findFirst().get();
				if(product.getStore() - store < carItem.getNum()){//库存低于临界值  不允许购买
					String result = "您选购的产品" + product.getTitle() + "库存不足";
					return result;
				}
			};
			//第二步  生成订单
			//按照不同的仓库将购物车分组
			ReceiveAddress receiveAddress = receiveAddressService.getById(addressId);
			Map<String, List<CarItem>> map = cars.stream().collect(Collectors.groupingBy(CarItem::getStorage));
			Iterator<String> ite = map.keySet().iterator();
			int fee = 0;
			while (ite.hasNext()) {
				String storage = ite.next();
				List<CarItem> carItems = map.get(storage);
				List<OrderItemList> lists = Lists.newArrayList();
				UserInfo userInfo = new UserInfo();
				Order order = new Order();
				for (CarItem carItem : carItems) {
					OrderItemList orderItemList = new OrderItemList();
					Product product = products.stream().filter(product1 -> carItem.getProductId().equals(Long.valueOf(product1.getId())))
							.findFirst().get();
					ProductDetail detail = productDetailLoader.getDetail(product);
					//填充orderItemList和userInfo
					fillParam(memberId, carItem.getNum(), detail, orderItemList, userInfo, receiveAddress);
					lists.add(orderItemList);
				}
				//确认订单
				//向海沧那边确认订单
				JSONObject object = new JSONObject();
				JSONArray array = new JSONArray();
				for (OrderItemList orderitemList :
						lists) {
					JSONObject jo = new JSONObject();
					jo.put("goodsId", orderitemList.getGoodsId());
					jo.put("skuId", orderitemList.getSkuId());
					jo.put("buyAmount", orderitemList.getBuyAmount());
					array.put(jo);
				}
				object.put("orderItemList", array);
				String itemStr = object.toString();
				object = new JSONObject();
				object.put("userInfo", new JSONObject(userInfo));
				//JSONObject objectUser = new JSONObject();
				//objectUser.put("userInfo",object);
				if(products.get(0).getType().equals(Product.TYPE_HT)){
					Integer result = CloudBuilderInteface.orderInfoConfirmation(order.getOrderNo(), itemStr, object.toString());
					if(!result.equals(HttpStatus.SC_OK)){//确认订单异常
						return -1;
					}
				}
				order.setMemberId(memberId);
				order.setPayMethod(payMethod);
				order.setCreateTime(new Date());
				order.setUpdateTime(new Date());
				order.setName(receiveAddress.getName());
				order.setMobile(receiveAddress.getMobile());
				order.setAddress(receiveAddress.getAddress());
				order.setIdentityNo(receiveAddress.getIdentityNo());
				order.setMemo(memo);
				if(products.get(0).getType().equals(Product.TYPE_HT)) {
					Integer result = CloudBuilderInteface.bookorder(order.getOrderNo(), itemStr, object.toString());
					if (!result.equals(HttpStatus.SC_OK)) {//下单异常
						return -1;
					}
				}
				orderService.save(order);
				orderIds.add(order.getId());//加入order的id集合中,方便回滚
				int totalNum = 0;
				int totalFee = 0;
				List<OrderItem> items = Lists.newArrayList();
				Integer postFee = sysDictionaryLoader.get(ProductConstant.CACHE_POST_FEE);
				Integer manPostFee = sysDictionaryLoader.get(ProductConstant.CACHE_MAN_POST);
				for (CarItem carItem : carItems) {
					Product product = products.stream().filter(product1 -> carItem.getProductId().equals(Long.valueOf(product1.getId())))
							.findFirst().get();
					ProductCount count = counts1.stream().filter(count1 -> carItem.getProductId().equals(Long.valueOf(count1.getProductId())))
							.findFirst().get();
					ProductDetail detail = productDetailLoader.getDetail(product);
					OrderItem item = new OrderItem();
					item.setOrderId(order.getId());
					item.setProductId(carItem.getProductId());
					item.setProductName(carItem.getProductName());
					item.setProductImg(carItem.getProductImage());
					item.setNum(carItem.getNum());
					item.setExpressFee(0);
					item.setTotalFee(new BigDecimal(carItem.getTotalFee() * 100).intValue());//以分为单位
					item.setMemberId(memberId);
					item.setCreateTime(new Date());
					item.setUpdateTime(new Date());
					items.add(item);
					totalNum = totalNum + carItem.getNum();
					totalFee = totalFee + item.getTotalFee();
					orderItemIds.add(item.getId());
					// todo 减库存
					product.setStore(product.getStore() - carItem.getNum());
					count.setSoldCount(count.getSoldCount() + carItem.getNum());
				}
				orderItemService.batchSave(items);
				order.setNum(totalNum);
				if(totalFee / 100 >= manPostFee){
					order.setTotalFee(totalFee + postFee*100);
					order.setExpressFee(postFee*100);
				} else {
					order.setTotalFee(totalFee);
					order.setExpressFee(0);
				}
				fee = fee + new BigDecimal(totalFee).intValue();
				orderService.update(order);
				orders.add(order);
			}
			//第三步  删除购物车中的产品并更改库存
			carItemService.delete(carIds);
			productService.batchUpdate(products);
			OrderPayRecord record = new OrderPayRecord();
			record.setOrderIds(orderIds);
			orderPayRecordService.save(record);
			FuzionMemberRedisDto member = memberService.getFuzionMemberRedisDto(memberId);
			if(products.get(0).getType().equals(Product.TYPE_SCORE)){//积分商城的产品直接扣除积分
				FuziongMemberStatistics fuziongMemberStatistics = fuziongMemberStatisticsService.getByMember(memberId);
				if(fuziongMemberStatistics.getNowTotalMoney() - fee < 0){ //积分不足
					return -2;
				} else {
					fuziongMemberStatistics.setNowTotalMoney(fuziongMemberStatistics.getNowTotalMoney() - fee);
					fuziongMemberStatisticsService.update(fuziongMemberStatistics);
					for (Order order :
							orders) {
						order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_PAY);
						order.setPayTime(new Date());
					}
					orderService.batchUpdate(orders);
					return 0;
				}
			}
			//海淘商品,现金购买
			/*WeixinConfig weixinConfig = weixinConfigService.getById(Long.valueOf(member.getWeixinId()));
			WeixinPaySignTool weixinPaySignTool = WeixinPayUtils.paySign(weixinConfig.getAppId(), weixinConfig.getMchId(), member.getOpenId(),
					record.getOrderNo(), spbillCreateIp, ProductConstant.WeixinPay.TRADETYPE, "购买"+products.get(0).getTitle()+"等"+products.size()+"产品",
					fee+StringUtils.EMPTY, resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL, weixinConfig.getMcKkey());*/
			KQPayInfo info = new KQPayInfo(record.getOrderNo(), new BigDecimal(fee).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_DOWN),
					memberId, products.get(0).getTitle()+"等", "1", resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL + "/" + record.getOrderNo(), "");
			String result = KQService.postAndResult(info);
			logger.info("******************KQService result***************" + result);
			storeProductCountService.batchUpdate(counts1);
			return result;
		} catch (Exception e) {
			Map<String, Object> param = Maps.newHashMapWithExpectedSize(1);
			if(!orderIds.isEmpty()){
				param.put("id in", orderIds);
				orderService.delete(param);
			}
			if(!orderItemIds.isEmpty()){
				param.clear();
				param.put("id in", orderItemIds);
				orderItemService.delete(param);
			}
			if(recordId != null){
				orderPayRecordService.delete(recordId);
			}
			if(!ops.isEmpty()){
				productService.batchUpdate(ops);
			}
			if(!counts.isEmpty()){
				storeProductCountService.batchUpdate(counts);
			}
			throw new RuntimeException(e);
		} finally {
			if(pids != null && !pids.isEmpty()){
				productDetailLoader.clearCache(pids);
				final List<Long> ids = pids;
				ExecutorService fixedThreadPool = Executors.newSingleThreadExecutor();//开启线程  往搜索引擎里加信息
				fixedThreadPool.execute(new Runnable(){
					@Override
					public void run() {
						try {
							for (Long id : ids) {
								productSolrClient.deleteDocument(id.toString());
								ProductDetail detail = productDetailLoader.get(id);
								ProductSearchDoc doc = new ProductSearchDoc();
								doc.setProductId(id);
								doc.setBrandId(detail.getBrandId());
								doc.setCategoryFullIdPath(detail.getCatId().toString());
								doc.setProductName(detail.getTitle() + ":::" + detail.getBrandName() + ":::" + detail.getCatName());
								doc.setPrice(detail.getRealPrice());
								doc.setSoldCount(detail.getSoldCount());
								doc.setReadCount(detail.getReadCount());
								doc.setType(detail.getType());
								productSearchService.buildProductSearchIndex(doc);
							}
						} catch (Exception e) {
							logger.error("carToOrder error", e);
						}
					}
				});
			}
		}
	}

	/**
	 * 微信支付异步回调操作  需要拆单的
	 * @param request
	 * @return
     */
	@Transactional
	public String weixinNofity(HttpServletRequest request, String recordNo){
		OrderPayRecord record = null;
		List<Order> list = Lists.newArrayList();
		try {
//			AlipayWapResult wapResult = WXPayService.notifyResult(request, ProductConstant.WeixinPay.KEY);
			KQResult result = KQService.verify(request);
//			String recordNo = result.getOutTradeNo();
			logger.info("************wapResult.getTrade_status()*********"+result.getTradeStatus());
			if (!result.getTradeStatus().equals(CommonConstants.SUCCESS.toUpperCase())) {
				logger.info("************签名校验失败*********recordId*********"+recordNo);
				return QK_NOTIFY_FAIL;
			}
			record = orderPayRecordService.getByField("orderNo",recordNo);
			logger.info("**********recordId**********"+recordNo+"**************"+record.toString());
			if(record == null || record.isLock() || record.isPay()){//已经支付或者被锁(正在执行)
				logger.info("************已经支付或者被锁(正在执行)*********recordId*********"+recordNo);
				return QK_NOTIFY_FAIL;
			}
			//先将这条记录锁起来,避免微信重复访问
			record.setLock(true);
			orderPayRecordService.update(record);
			//获得所有的订单id
			List<Long> orderIds = record.getOrderIds();
			List<Order> orders = orderService.getByIds(orderIds);
			list = orders;
			for (Order order : orders) {
				order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_PAY);
				order.setPayMethod(ProductConstant.OrderStatic.PAY_WX);
				order.setPayTime(new Date());
			}
			//批量修改订单状态
			orderService.batchUpdate(orders);
			record.setPay(true);
			orderPayRecordService.update(record);
			return QK_NOTIFY_SUCCESS.replace("{url}", resourceHolder.getStringValue("webRoot") + "/store/weixin/order/success");
		} catch (Exception e) {
			// 回滚
			if(record != null){
				record.setPay(false);
				record.setLock(false);
				orderPayRecordService.update(record);
			}
			if(!list.isEmpty()){
				orderService.batchUpdate(list);
			}
			return QK_NOTIFY_FAIL;
		}
	}

	/**
	 * 在我的订单页里面针对单笔订单进行支付
	 * @param orderId
	 * @param spbillCreateIp
	 * @return
	 * @throws Exception
     */
	public Object singleOrderPay(Long orderId, String spbillCreateIp) throws Exception{
		Order order = orderService.getById(orderId);
		//海淘商品,现金购买
		List<OrderItem> list = orderItemService.findByField("orderId", orderId);
		Long productId = list.get(0).getProductId();
		ProductDetail detail = productDetailLoader.get(productId);
		FuzionMemberRedisDto member = memberService.getFuzionMemberRedisDto(order.getMemberId());
		if(detail.getType().equals(Product.TYPE_HT)){
			/*WeixinConfig weixinConfig = weixinConfigService.getById(Long.valueOf(member.getWeixinId()));
			WeixinPaySignTool weixinPaySignTool = WeixinPayUtils.paySign(weixinConfig.getAppId(), weixinConfig.getMchId(), member.getOpenId(),
					order.getOrderNo(), spbillCreateIp, ProductConstant.WeixinPay.TRADETYPE, "购买"+list.get(0).getProductName()+"等"+list.size()+"产品",
					order.getTotalFee()+StringUtils.EMPTY, resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL_SINGLE, weixinConfig.getMcKkey());*/
			KQPayInfo info = new KQPayInfo(order.getOrderNo(), new BigDecimal(order.getTotalFee()).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_DOWN),
					order.getMemberId(), list.get(0).getProductName()+"等", order.getNum().toString(), resourceHolder.getStringValue("webRoot")+ProductConstant.WeixinPay.NOTIFYURL_SINGLE + "/" + order.getOrderNo(), "");
			String result = KQService.postAndResult(info);
			logger.info("******************KQService result***************" + result);
			return result;
		} else {
			FuziongMemberStatistics fuziongMemberStatistics = fuziongMemberStatisticsService.getByMember(order.getMemberId());
			if(fuziongMemberStatistics.getNowTotalMoney() - order.getTotalFee() < 0){ //积分不足
				return -2;
			} else {
				fuziongMemberStatistics.setNowTotalMoney(fuziongMemberStatistics.getNowTotalMoney() - order.getTotalFee());
				fuziongMemberStatisticsService.update(fuziongMemberStatistics);
				return 0;
			}
		}
	}

	/**
	 * 单笔订单支付异步回调
	 * @param request
	 * @return
     */
	@Transactional
	public String weixinNotifySingle(HttpServletRequest request, String recordId){
		Order oo = null;
		try {
//			AlipayWapResult wapResult = WXPayService.notifyResult(request, ProductConstant.WeixinPay.KEY);
			KQResult result = KQService.verify(request);
//			String recordId = result.getOutTradeNo();
			logger.info("************wapResult.getTrade_status()*********"+result.getTradeStatus());
			if (!result.getTradeStatus().equals(CommonConstants.SUCCESS.toUpperCase())) {
				logger.info("************签名校验失败*********recordId*********"+recordId);
				return QK_NOTIFY_FAIL;
			}
			Order order = orderService.getByField("orderNo", recordId);
			logger.info("****************order******************" + order.toString());
			if(order == null || !order.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_CREATE)){
				return QK_NOTIFY_FAIL;
			}
			oo = order;
			order.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_PAY);
			order.setPayMethod(ProductConstant.OrderStatic.PAY_WX);
			order.setPayTime(new Date());

			orderService.update(order);

			return QK_NOTIFY_SUCCESS.replace("{url}", resourceHolder.getStringValue("webRoot") + "/store/weixin/order/success");
		} catch (Exception e) {
			if(oo != null){
				orderService.update(oo);
			}
			logger.error("weixinNotifySingle error", e);
			return QK_NOTIFY_FAIL;
		}
	}

	/**
	 * 分页获取我的订单
	 * @param memberId
	 * @param status
	 * @param request
     * @return
     */
	public List<Order> myOrder(Long memberId, Integer status, HttpServletRequest request){
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
		param.put("memberId", memberId);
		param.put("isDeleted", 0);
		if(status != null){
			param.put("status", status);
		}
		Page<Order> page = orderService.pageQuery(param, request);
		for (Order order : page.getData()) {
			List<OrderItem> items = orderItemService.findByField("orderId", order.getId());
			order.setItems(items);
		}
		return page.getData();
	}

	/**
	 * 确认收货
	 * @param orderId
     */
	@Transactional
	public void confirmGet(Long orderId){
		Order order = orderService.getById(orderId);
		IncomeExpenditureRecords sellRecords = null;
		try {
			Order order1 = order;
			if(order1 != null && order1.getStatus().equals(ProductConstant.OrderStatic.ORDER_STATUS_SEND)){
				order1.setStatus(ProductConstant.OrderStatic.ORDER_STATUS_SUCCESS);
				order1.setFinishedTime(new Date());
				orderService.update(order1);
				//更改当天的营业额
				List<OrderItem> items = orderItemService.findByField("orderId", orderId);
				ProductDetail detail = productDetailLoader.get(items.get(0).getProductId());
				if(detail.getType().equals(Product.TYPE_SCORE)){
					FuzionMemberRedisDto dto = memberService.getFuzionMemberRedisDto(order.getMemberId());
					// 卖家账户余额变动
					int fee = new BigDecimal(sysDictionaryLoader.get(ProductConstant.CACHE_SCORE_PRODUCT_AMOUNT_SCALE)).divide(new BigDecimal(100)).multiply(new BigDecimal(order.getTotalFee())).intValue();
					FuziongMemberStatistics sellerStatistics = fuziongMemberStatisticsMapper.getBySellerId(dto.getSellerId());
					sellerStatistics.setTotalMoney(sellerStatistics.getTotalMoney() + fee);
					sellerStatistics.setNowTotalMoney(sellerStatistics.getNowTotalMoney() + fee);
					fuziongMemberStatisticsMapper.update(sellerStatistics);
					//卖家账户明细记录
					sellRecords = new IncomeExpenditureRecords();
					sellRecords.setMemberId(dto.getSellerId());
					sellRecords.setType(FuzionConstants.TYPE_TWO);
					sellRecords.setMoney(fee);
					sellRecords.setObjType(FuzionConstants.IncomeExpenditure.BEAN_SHOPPING);
					sellRecords.setObjId(String.valueOf(order.getId()));
					incomeExpenditureRecordsService.insert(sellRecords);
				}
			}
		} catch (Exception e) {
			orderService.update(order);
			if(sellRecords != null){
				incomeExpenditureRecordsService.delete(sellRecords.getId());
			}
			throw new RuntimeException(e);
		}
	}

}
